package com.jt.demo2.aop;

//AOP 面向切面编程   1年开发
//知识铺垫: 切面 = 动态代理+方法的扩展  后期被AOP API封装
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;


import java.util.Arrays;


@Component //将这个类交给Spring容器管理
@Aspect    //标识当前类是一个切面
public class TxAspect {
    //编码:  切面 = 切入点表达式 + 通知方法
    //切入点表达式:为谁创建代理对象!!!
    //@Pointcut("bean(userServiceImpl)") 一个
    //@Pointcut("within(com.jt.demo2.service.*)") //多个
    //@Pointcut("execution(void com.jt.demo2.service.UserServiceImpl.addUser())")
    //@Pointcut("execution(* com.jt.demo2.service..*.*(..))")
    @Pointcut("@annotation(com.jt.demo2.anno.TX)")

    //@Pointcut("@@annotation(自定义注解)")
    public void pointCut(){

    }

    //通知方法:对原有方法的扩展
    @Before("pointCut()")
    public void before(JoinPoint joinPoint){
        //1.获取目标对象的类型
        Class targetClass = joinPoint.getTarget().getClass();
        //2.获取目标对象名称
        String targetName = joinPoint.getSignature().getDeclaringTypeName();
        //3.获取目标方法的名称
        String methodName = joinPoint.getSignature().getName();
        //4.获取参数数据
        Object[] args = joinPoint.getArgs();

        System.out.println("目标对象类型:"+targetClass);
        System.out.println("目标对象名称:"+targetName);
        System.out.println("目标对象方法名:"+methodName);
        System.out.println("参数名称:"+ Arrays.toString(args));
    }

    @AfterReturning("pointCut()")
    public void afterReturning(){
        System.out.println("AOP后置通知");
    }

    @AfterThrowing("pointCut()")
    public void afterThrowing(){
        System.out.println("抛出异常!!!");
    }

    @After("pointCut()")
    public void after(){
        System.out.println("我是最终通知!!");
    }

    /*
    * 注意事项:环绕通知中必须添加参数,并且必须位于第一位
    * @return
    * */
    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕通知开始");
        Object result = joinPoint.proceed();
        System.out.println("环绕通知结束");
        return result;
    }
}
